/*******************************************************************************
 * Copyright (c) 2011 Jovansonlee B. Cesar.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * 
 * Contributors:
 *     Jovansonlee B. Cesar - initial API and implementation
 ******************************************************************************/
package com.ivanceras.client.widgets;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.TreeMap;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.http.client.URL;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
import com.ivanceras.client.DataService;
import com.ivanceras.client.DataServiceAsync;

public class DataImporterUI extends Composite{

	private static DataImporterUIUiBinder uiBinder = GWT
			.create(DataImporterUIUiBinder.class);

	private final DataServiceAsync dataService = GWT
	.create(DataService.class);
	
	interface DataImporterUIUiBinder extends UiBinder<Widget, DataImporterUI> {
	}

	public DataImporterUI() {
		initWidget(uiBinder.createAndBindUi(this));
		itemsperpagetextbox.setText(itemsPerPage.toString());
	}

	@UiField
	Button button;
	
	@UiField
	TextBox httpurl;
	
	@UiField
	TextBox tablelistservlet;
	
	@UiField
	TextBox dataservlet;
	
	@UiField
	HTML statusUpdate;
	
	Integer itemsPerPage = 100;

	@UiField
	TextBox itemsperpagetextbox;
	
	@UiField
	TextBox tabletext;
	
	@UiField
	TextBox specifictables;
	
	
	@UiHandler("button")
	void onDataImportClick(ClickEvent e) {
		String xmlUrl = httpurl.getText()+tablelistservlet.getText();

		String specificTable = specifictables.getText().trim();
		String tablePattern = tabletext.getText();
		if(!specificTable.equals("")){
			String url = URL.encode(specificTable);
			xmlUrl = xmlUrl+"?tables="+url;
		}
		else if(tablePattern != null && !tablePattern.trim().equals("")){
			String urlTablePattern = URL.encode(tablePattern.trim());
			xmlUrl = xmlUrl+"?pattern="+urlTablePattern;
		}
		initializeImport(xmlUrl);
	}
	
	void initializeImport(String tableListUrl){
		String s_itemsPerPage = itemsperpagetextbox.getText();
		if(s_itemsPerPage != null && !s_itemsPerPage.trim().equals("")){
			itemsPerPage = Integer.parseInt(s_itemsPerPage);
		}
		getTableList(tableListUrl);
	}

	private void getTableList(String xmlurl) {
		dataService.getTableList(xmlurl, new AsyncCallback<HashMap<String,Integer>>() {

			@Override
			public void onFailure(Throwable caught) {
				caught.printStackTrace();
			}

			@Override
			public void onSuccess(HashMap<String, Integer> result) {
				initiateTableImport(result);
			}
		});
	}

	

	Iterator<Entry<String, Integer>> tableCountList = null;
	
	void initiateTableImport(HashMap<String, Integer> tableCountList){
		TreeMap<String, Integer> treemap = new TreeMap<String, Integer>();
		treemap.putAll(tableCountList);
		this.tableCountList = treemap.entrySet().iterator();
		importUrl();
	}
	
	protected String getXmlUrl(String table, Integer page,
			Integer itemsPerPage) {
		String xmldataurl = httpurl.getText()+""+dataservlet.getText()+"?table="+table+"&page="+page+"&items="+itemsPerPage;
		return xmldataurl;
	}

	int totalPage(int totalCount, int itemPerPage){
		return totalCount / itemPerPage + (totalCount % itemPerPage > 0 ? 1 : 0);
	}

	HashMap<String, Integer> tablePage = new HashMap<String, Integer>();
	
	Entry<String, Integer> currentItem = null;
	
	boolean first = true;
	
	Integer currentPage = 0;
	
	void importUrl(){
		if(!tableCountList.hasNext()){
			return;
		}
		if(first){
			currentItem = tableCountList.next();
			first = false;
		}
		String table = currentItem.getKey();
		Integer totalCount = currentItem.getValue();
		final int totalPage = totalPage(totalCount, itemsPerPage);
		if(!tablePage.containsKey(table)){
			currentPage = 1;
		}
		tablePage.put(table, currentPage);
		System.out.println("page "+currentPage+" of "+totalPage+" with "+totalCount+" total records from "+table);
		statusUpdate.setHTML("Importing page "+currentPage+" of "+totalPage+" from table: "+table);
		String xmlurl = getXmlUrl(table, currentPage, itemsPerPage); 
		dataService.importDaoXmlFromUrl(xmlurl, new AsyncCallback<Boolean>() {
			
			@Override
			public void onSuccess(Boolean result) {
				System.out.println("Done!.. "+(result ? "Sucess" : "Fail"));
				Timer t = new Timer(){

					@Override
					public void run() {
						importUrl();
					}
					
				};
				currentPage++;
				if(currentPage > totalPage){
					if(tableCountList.hasNext()){
						currentItem = tableCountList.next();
						System.out.println("Next table..."+currentItem.getKey()+" with "+currentItem.getValue()+" records...");
					}else{
						System.err.println("Done Importing all tables.... SUCESSS!!! ");
						return;
					}
				}
				t.schedule(1);
			}
			
			@Override
			public void onFailure(Throwable caught) {
				System.err.println("Error!");
				caught.printStackTrace();
				System.out.println("Resuming due to last error");
				Timer t = new Timer(){

					@Override
					public void run() {
						importUrl();
					}
					
				};
				t.schedule(3000);
			}
		});


	}
}
